package com.gupaoedu.vip.pattern.springmvc2.webmvc.servlet;

import com.gupaoedu.vip.pattern.springmvc1.annotation.MyRequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class MyHandlerAdapter {

    public boolean supports(Object handler){return handler instanceof MyHandlerMapping;}

    public Object handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        MyHandlerMapping handlerMapping = (MyHandlerMapping) handler;
        //把参数的形参列表一一对应
        Map<String, Integer> paramIndexMapping = new HashMap<String, Integer>();
        Annotation [] [] pa = handlerMapping.getMethod().getParameterAnnotations();
        for (int i = 0; i < pa.length; i++) {
            for (Annotation annotation : pa[i]) {
                if(annotation instanceof MyRequestParam){
                    String paramName = ((MyRequestParam) annotation).value();
                    if(!"".equals(paramName)){
                        paramIndexMapping.put(paramName, i);
                    }
                }
            }
        }

        Class<?> [] paramTypes = handlerMapping.getMethod().getParameterTypes();
        for (int i = 0; i < paramTypes.length; i++) {
            Class<?> type = paramTypes[i];
            if(type==HttpServletRequest.class||type==HttpServletResponse.class){
                paramIndexMapping.put(type.getName(), i);
            }
        }
        //获得方法的参数并用来赋值调用
        Map<String,String [] > params = request.getParameterMap();
        Object[] paramsValues = new Object[paramTypes.length];
        for (Map.Entry<String, String[]> param : params.entrySet()) {
            String value = Arrays.toString(param.getValue()).replaceAll("\\[|\\]", "")
                    .replaceAll("\\s","");
            if(!paramIndexMapping.containsKey(param.getKey())){continue;}
            int index = paramIndexMapping.get(param.getKey());
            paramsValues[index] = caseStringValue(value,paramTypes[index]);
        }
        if(paramIndexMapping.containsKey(HttpServletRequest.class.getName())){
            int index = paramIndexMapping.get(HttpServletRequest.class.getName());
            paramsValues[index] = request;
        }
        if(paramIndexMapping.containsKey(HttpServletResponse.class.getName())){
            int index = paramIndexMapping.get(HttpServletResponse.class.getName());
            paramsValues[index] = response;
        }
        Object result = handlerMapping.getMethod().invoke(handlerMapping.getController(), paramsValues);
        if(result==null||result instanceof Void){
            return null;
        }
        return result;
    }

    private Object caseStringValue(String value, Class<?> paramType) {
        if(String.class == paramType){
            return value;
        }
        if(Integer.class == paramType){
            return Integer.valueOf(value);
        }else if (Double.class==paramType){
            return Double.valueOf(value);
        }else{
            if(value!=null){
                return value;
            }
            return null;
        }
    }
}
